package com.osell.selection.ui.main;

import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.StyleSpan;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.da.lon.wang.xlg.R;
import com.da.lon.wang.xlg.activity.ProductsActivity;
import com.google.android.flexbox.FlexboxLayout;
import com.osell.selection.data.entity.PageResult;
import com.osell.selection.data.network.RestAPI;
import com.osell.selection.data.network.entity.Product;
import com.osell.selection.data.network.entity.ResponseData;
import com.osell.selection.data.network.entity.StoreHomeInfo;
import com.osell.selection.ui.base.LoadMoreAdapter;
import com.osell.selection.ui.base.RecyclerFragment;
import com.osell.selection.ui.base.SlimAdapter;
import com.osell.selection.ui.category.CategoriesActivity;
import com.osell.selection.ui.common.WebViewActivity;
import com.osell.selection.util.DimenUtils;
import com.osell.selection.util.Spans;
import com.osell.selection.widget.AutoViewPager;
import com.osell.selection.widget.MyGridView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class StoreFragment extends RecyclerFragment<Object> {

    AutoViewPager vp_top_banner;
    MyGridView gv_activities;

    private SlimAdapter mAdapter;

    private Single<ResponseData<StoreHomeInfo>> mSingleStoreHomeInfo;
    private Disposable mDisposable;

    @Override
    protected int getLayoutResource() {
        return R.layout.fragment_store;
    }

    @Override
    public RecyclerView.Adapter onCreateAdapter(List<Object> data) {
        mAdapter = SlimAdapter.create()
                .register(new SlimAdapter.SlimInjector<Product>() {

                    @Override
                    public int onGetLayoutResource() {
                        return R.layout.store_product_item;
                    }

                    @Override
                    public void onInit(SlimAdapter.SlimViewHolder<Product> viewHolder) {
                        viewHolder.clicked(v -> v.getContext().startActivity(new Intent(v.getContext(), ProductsActivity.class)
                                .putExtra("product_number", viewHolder.itemData.number)));
                    }

                    @Override
                    public void onBind(Product data, SlimAdapter.SlimViewHolder<Product> viewHolder) {
                        int position = mAdapter.getData().indexOf(viewHolder.itemData);
                        int prePosition = position - 1;
                        viewHolder.text(R.id.tv_product_name, data.name)
                                .text(R.id.tv_product_silk_price, new Spans()
                                        .append(data.price,
                                                new ForegroundColorSpan(ContextCompat.getColor(viewHolder.itemView.getContext(), R.color.colorPrimary)),
                                                new StyleSpan(Typeface.BOLD))
                                        .append(" ")
                                        .append(getString(R.string.silk))
                                        .append(" ")
                                        .append("*", new ImageSpan(viewHolder.itemView.getContext(), R.drawable.ic_silk_total_amount)))
                                .text(R.id.tv_store_tag, data.storeTagName)
                                .visibility(R.id.tv_store_tag, position == 0
                                        || (prePosition >= 0 && !(mAdapter.getData().get(prePosition) instanceof Product)) ? View.VISIBLE : View.GONE);
                        Glide.with(viewHolder.itemView.getContext())
                                .load(data.imageUrl)
                                .placeholder(R.drawable.inset_place_holder_logo)
                                .centerCrop()
                                .into((ImageView) viewHolder.id(R.id.iv_product_image));
                    }
                })
                .register(new SlimAdapter.SlimInjector<StoreHomeInfo.Banners>() {

                    @Override
                    public int onGetLayoutResource() {
                        return R.layout.store_image_item;
                    }

                    @Override
                    public void onBind(StoreHomeInfo.Banners data, SlimAdapter.SlimViewHolder<StoreHomeInfo.Banners> viewHolder) {
                        Context context = viewHolder.itemView.getContext();
                        FlexboxLayout fbl_banner = viewHolder.id(R.id.fbl_banner);
                        fbl_banner.removeAllViews();
                        LayoutInflater layoutInflater = LayoutInflater.from(fbl_banner.getContext());
                        for (StoreHomeInfo.Banner banner : data.banners) {
                            ImageView iv_banner = (ImageView) layoutInflater.inflate(R.layout.flex_box_banner_item, fbl_banner, false);
                            ((FlexboxLayout.LayoutParams) iv_banner.getLayoutParams()).setWidth(
                                    (int) (DimenUtils.dipToPixels(new Random().nextInt(100), context) + DimenUtils.dipToPixels(100, context)));
                            iv_banner.setOnClickListener(v -> v.getContext().startActivity(
                                    new Intent(v.getContext(), WebViewActivity.class).putExtra("url", banner.link)));
                            fbl_banner.addView(iv_banner);
                            Glide.with(fbl_banner.getContext())
                                    .load(banner.image)
                                    .centerCrop()
                                    .into(iv_banner);
                        }
                        viewHolder.text(R.id.tv_image_tag_name, data.banners.get(0).name);
                    }
                })
                .enableDiff();
        return mAdapter;
    }

    @Override
    public void onLoadMoreAdapterCreated(LoadMoreAdapter loadMoreAdapter) {
        View header = LayoutInflater.from(recycler_view.getContext())
                .inflate(R.layout.store_product_header, recycler_view, false);
        vp_top_banner = header.findViewById(R.id.vp_top_banner);
        gv_activities = header.findViewById(R.id.gv_activities);
        loadMoreAdapter.addHeader(header);
    }

    @Override
    public Observable<PageResult<Object>> onCreatePageObservable(int currentPage) {
        mSingleStoreHomeInfo = RestAPI.getInstance().oSellService()
                .getStoreHomeInfo().cache();
        if (mDisposable != null) {
            mDisposable.dispose();
        }
        mDisposable = mSingleStoreHomeInfo
                .toObservable()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(storeHomeInfoResponseData -> {
                            vp_top_banner.setAdapter(new TopBannerAdapter(storeHomeInfoResponseData.data.topBanners));
                            vp_top_banner.setOffscreenPageLimit(2);
                            gv_activities.setAdapter(new ActAdapter(storeHomeInfoResponseData.data.activities));
                        },
                        throwable -> {
                        });
        return mSingleStoreHomeInfo
                .map(storeHomeInfoResponseData -> {
                    PageResult<Object> result = new PageResult<>();
                    result.page_number = currentPage;
                    result.total_pages = 1;
                    result.elements = new ArrayList<>();
                    for (List<StoreHomeInfo.Banner> banners : storeHomeInfoResponseData.data.bottomeBanners) {
                        boolean containProduct = false;
                        for (StoreHomeInfo.Banner banner : banners) {
                            if (banner.products != null && !banner.products.isEmpty()) {
                                containProduct = true;
                                break;
                            }
                        }
                        if (containProduct) {
                            banners.get(0).products.get(0).storeTagName = banners.get(0).name;
                            result.elements.addAll(banners.get(0).products);
                        } else {
                            StoreHomeInfo.Banners bannersO = new StoreHomeInfo.Banners();
                            bannersO.banners = banners;
                            result.elements.add(bannersO);
                        }
                    }
                    result.page_size = result.elements.size();
                    result.total_elements = result.elements.size();
                    return result;
                })
                .toObservable()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .cache();
    }

    @Override
    public void notifyDataChanged(List<Object> data) {
        mAdapter.updateData(data);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        swipe_refresh_layout.setColorSchemeResources(R.color.colorPrimary);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(view.getContext(), 2);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (position - 1 >= 0) {
                    if (mAdapter.getItem(position - 1) instanceof Product) {
                        return 1;
                    } else {
                        return 2;
                    }
                }
                return 0;
            }
        });
        recycler_view.setLayoutManager(gridLayoutManager);
        super.onViewCreated(view, savedInstanceState);

        gv_activities.setOnItemClickListener((parent, v, position, id) -> {
            StoreHomeInfo.Act act = ((StoreHomeInfo.Act) parent.getItemAtPosition(position));
            if (!TextUtils.isEmpty(act.link) && act.link.contains("Index-category")) {
                v.getContext().startActivity(new Intent(v.getContext(), CategoriesActivity.class));
            } else {
                v.getContext().startActivity(new Intent(v.getContext(), WebViewActivity.class)
                        .putExtra("url", act.link));
            }
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mDisposable != null) {
            mDisposable.dispose();
        }
    }

    public static class TopBannerAdapter extends PagerAdapter {

        private List<View> mRecycledViews = new ArrayList<>();

        private List<StoreHomeInfo.Banner> mData;

        TopBannerAdapter(List<StoreHomeInfo.Banner> data) {
            this.mData = data;
        }

        @Override
        public int getCount() {
            return mData == null ? 0 : mData.size();
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            container.removeView((View) object);
            mRecycledViews.add((View) object);
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, final int position) {
            ImageView view;
            if (mRecycledViews.isEmpty()) {
                view = new ImageView(container.getContext());
                view.setScaleType(ImageView.ScaleType.CENTER_CROP);
            } else {
                view = (ImageView) mRecycledViews.get(0);
                mRecycledViews.remove(0);
            }
            StoreHomeInfo.Banner item = mData.get(position);
            Glide.with(container.getContext())
                    .load(item.image)
                    .centerCrop()
                    .into(view);
            view.setOnClickListener(v -> v.getContext().startActivity(
                    new Intent(v.getContext(), WebViewActivity.class).putExtra("url", item.link)));
            container.addView(view);
            return view;
        }
    }

    public static class ActAdapter extends BaseAdapter {

        private List<StoreHomeInfo.Act> mData;

        private int mSize;

        ActAdapter(List<StoreHomeInfo.Act> data) {
            this.mData = data;
        }

        @Override
        public int getCount() {
            return mData == null ? 0 : mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Context context = parent.getContext();
            if (mSize == 0) {
                mSize = (int) DimenUtils.dipToPixels(50, context);
            }
            TextView v = new TextView(context);
            v.setTextColor(ContextCompat.getColor(context, R.color.colorTextGray));
            v.setCompoundDrawablePadding((int) DimenUtils.dipToPixels(8, context));
            v.setGravity(Gravity.CENTER_HORIZONTAL);
            StoreHomeInfo.Act item = mData.get(position);
            Glide.with(context)
                    .load(item.image)
                    .into(new SimpleTarget<GlideDrawable>() {
                        @Override
                        public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation) {
                            glideDrawable.setBounds(0, 0, mSize, mSize);
                            v.setCompoundDrawables(null, glideDrawable, null, null);
                        }
                    });
            v.setText(item.name);
            return v;
        }
    }
}